/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jackrabbit.test.api.version;
import javax.jcr.nodetype.NodeType;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.version.Version;
import javax.jcr.ItemVisitor;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Property;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.ItemNotFoundException;
import javax.jcr.PropertyIterator;
import javax.jcr.Value;
import javax.jcr.PropertyType;
import javax.jcr.lock.LockException;
import java.util.GregorianCalendar;
import java.util.Calendar;
import java.util.List;
import java.util.Arrays;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
/**
* <code>VersionTest</code> covers tests related to the methods of the {@link
* javax.jcr.version.Version} class.
*
* @test
* @sources VersionTest.java
* @executeClass org.apache.jackrabbit.test.api.version.VersionTest
* @keywords versioning
*/
public class VersionTest extends AbstractVersionTest {
private Version version;
private Version version2;
/**
* helper class used in testAccept()
*/
private class ItemVisitorTest implements ItemVisitor {
Node ivtNode;
public ItemVisitorTest(Version v) {
ivtNode = v;
}
public void visit(Node node) throws RepositoryException {
assertTrue("Version.accept(ItemVisitor) does not provide the right node to the ItemVisitor", ivtNode.isSame(node));
}
public void visit(Property property) throws RepositoryException {
}
}
protected void setUp() throws Exception {
super.setUp();
// create two versions
version = versionableNode.checkin();
versionableNode.checkout();
version2 = versionableNode.checkin();
}
protected void tearDown() throws Exception {
// check the node out, so that it can be removed
versionableNode.checkout();
version = null;
version2 = null;
super.tearDown();
}
/**
* Tests if <code>Version.accept(ItemVisitor)</code> accepts a ItemVisitor
* and if the right Node is provided to that visitor.
*/
public void testAccept() throws Exception {
ItemVisitorTest ivt = new ItemVisitorTest(version);
version.accept(ivt);
}
/**
* Tests if <code>Version.addMixin(String)</code> throws a {@link
* javax.jcr.nodetype.ConstraintViolationException}
*/
public void testAddMixin() throws Exception {
try {
version.addMixin(mixVersionable);
fail("Version should be read-only: Version.addMixin(String) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
}
/**
* Tests if <code>Version.addNode(String)</code> and
* <code>Version.addNode(String, String)</code> throw a {@link
* javax.jcr.nodetype.ConstraintViolationException}
*/
public void testAddNode() throws Exception {
try {
version.addNode(nodeName4);
version.save();
fail("Version should be read-only: Version.addNode(String) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
try {
version.addNode(nodeName4, ntBase);
version.save();
fail("Version should be read-only: Version.addNode(String,String) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
}
/**
* Tests if <code>Version.canAddMixin(String)</code> returns
* <code>false</code>
*/
public void testCanAddMixin() throws Exception {
assertFalse("Version should be read-only: Version.canAddMixin(String) returned true", version.canAddMixin(mixVersionable));
}
/**
* Tests if <code>Version.cancelMerge(Version)</code> throws an {@link
* javax.jcr.UnsupportedRepositoryOperationException}
*/
public void testCancelMerge() throws Exception {
try {
version.cancelMerge(version2);
fail("Version.cancelMerge(Version) did not throw an UnsupportedRepositoryOperationException");
} catch (UnsupportedRepositoryOperationException success) {
}
}
/**
* Tests if <code>Version.checkin()</code> throws an {@link
* javax.jcr.UnsupportedRepositoryOperationException}
*/
public void testCheckin() throws Exception {
try {
version.checkin();
fail("Version.checkin() did not throw an UnsupportedRepositoryOperationException");
} catch (UnsupportedRepositoryOperationException success) {
}
}
/**
* Tests if <code>Version.checkout()</code> throws an {@link
* javax.jcr.UnsupportedRepositoryOperationException}
*/
public void testCheckout() throws Exception {
try {
version.checkout();
fail("Version.checkout() did not throw an UnsupportedRepositoryOperationException");
} catch (UnsupportedRepositoryOperationException success) {
}
}
/**
* Tests if <code>Version.doneMerge(Version)</code> throws an {@link
* javax.jcr.UnsupportedRepositoryOperationException}
*/
public void testDoneMerge() throws Exception {
try {
version.doneMerge(version2);
fail("Version should not be versionable: Version.doneMerge(Version) did not throw an UnsupportedRepositoryOperationException");
} catch (UnsupportedRepositoryOperationException success) {
}
}
/**
* Tests if <code>Version.getAncestor(int)</code> returns the right
* ancestor
*/
public void testGetAncestor() throws Exception {
assertTrue("Version.getAncestor(int) does not work", superuser.getRootNode().isSame(version.getAncestor(0)));
}
/**
* Tests if <code>Version.getBaseVersion()</code> throws an {@link
* javax.jcr.UnsupportedRepositoryOperationException}
*/
public void testGetBaseVersion() throws Exception {
try {
version.getBaseVersion();
fail("Version.getBaseVersion() did not throw an UnsupportedRepositoryOperationException");
} catch (UnsupportedRepositoryOperationException success) {
}
}
/**
* Tests if <code>Version.getCorrespondingNodePath(String)</code> returns
* the right path
*/
public void testGetCorrespondingNodePath() throws Exception {
assertEquals("Version.getCorrespondingNodePath(String) did not return the right path", version.getPath(), version.getCorrespondingNodePath(workspaceName));
}
/**
* Tests if <code>Version.getDepth()</code> returns the right depth
*/
public void testGetDepth() throws Exception {
assertTrue("Version.getDepth() mismatch", version.getDepth() >= 4);
}
/**
* Tests if <code>Version.getIndex()</code> returns the right index
*/
public void testGetIndex() throws Exception {
assertEquals("Version.getIndex() mismatch", 1, version.getIndex());
}
/**
* Tests if <code>Version.getLock()</code> throws a {@link
* javax.jcr.lock.LockException}
*/
public void testGetLock() throws Exception {
try {
version.getLock();
fail("Version should not be lockable: Version.getLock() did not throw a LockException");
} catch (LockException success) {
}
}
/**
* Tests if <code>Version.getMixinNodeTypes()</code> does not return null.
*/
public void testGetMixinNodeTypes() throws Exception {
NodeType[] ntArray = version.getMixinNodeTypes();
assertNotNull("Version.getMixinNodeTypes returns null array", ntArray);
}
/**
* Tests if <code>Version.getName()</code> returns the right name
*/
public void testGetName() throws Exception {
assertTrue("Version.getName() does not return the right name", versionableNode.getVersionHistory().getVersion(version.getName()).isSame(version));
}
/**
* Tests if <code>Version.getNode(String)</code> returns the right child
* Node
*/
public void testGetNode() throws Exception {
assertTrue("Version.getNode(String) does not return a sub-node of type nt:frozenNode", version.getNode(jcrFrozenNode).isNodeType(ntFrozenNode));
}
/**
* Tests if <code>Version.getNodes()</code> and <code>Version.getNodes(String)</code>
* returns the right child Node
*/
public void testGetNodes() throws Exception {
assertTrue("Version.getNodes() does not return a sub-node of type nt:frozenNode", version.getNodes().nextNode().isNodeType(ntFrozenNode));
assertTrue("Version.getNodes(String) does not return a sub-node of type nt:frozenNode", version.getNodes(superuser.getNamespacePrefix(NS_JCR_URI) + ":*").nextNode().isNodeType(ntFrozenNode));
}
/**
* Tests if <code>Version.getParent()</code> returns the right parent Node
*/
public void testGetParent() throws Exception {
assertTrue("Version.getParent() does not return a parent-node of type nt:versionHistory", version.getParent().isNodeType(ntVersionHistory));
}
/**
* Tests if <code>Version.getPath()</code> returns the right path
*/
public void testGetPath() throws Exception {
assertTrue("Version.getPath() does not return the right path", version.getPath().startsWith("/" + superuser.getNamespacePrefix(NS_JCR_URI) + ":system/" + superuser.getNamespacePrefix(NS_JCR_URI) + ":versionStorage/"));
}
/**
* Tests if <code>Version.getPrimaryItem()</code> throws a {@link
* javax.jcr.ItemNotFoundException}
*/
public void testGetPrimaryItem() throws Exception {
try {
version.getPrimaryItem();
fail("Version.getPrimaryItem() did not throw a ItemNotFoundException");
} catch (ItemNotFoundException success) {
}
}
/**
* Tests if <code>Version.getPrimaryNodeType()</code> returns the right
* primary node type <code>nt:version</code>
*/
public void testGetPrimaryNodeType() throws Exception {
assertEquals("Version does not have the primary node type nt:version", ntVersion, version.getPrimaryNodeType().getName());
}
/**
* Tests if <code>Version.getProperties()</code> and
* <code>Version.getProperties(String)</code> return the right property
*/
public void testGetProperties() throws Exception {
PropertyIterator pi = version.getProperties();
boolean hasPropertyCreated = false;
while (pi.hasNext()) {
if (pi.nextProperty().getName().equals(jcrCreated)) {
hasPropertyCreated = true;
}
}
assertTrue("Version.getProperties() does not return property jcr:created", hasPropertyCreated);
pi = version.getProperties(superuser.getNamespacePrefix(NS_JCR_URI) + ":*");
hasPropertyCreated = false;
while (pi.hasNext()) {
if (pi.nextProperty().getName().equals(jcrCreated)) {
hasPropertyCreated = true;
}
}
assertTrue("Version.getProperties(String) does not return property jcr:created", hasPropertyCreated);
}
/**
* Tests if <code>Version.getProperty(String)</code> returns the right
* property
*/
public void testGetProperty() throws Exception {
assertTrue("Version.getProperty(String) does not return property jcr:created", version.getProperty(jcrCreated).getName().equals(jcrCreated));
}
/**
* Tests if <code>Version.getSession()</code> returns the right session
*/
public void testGetSession() throws Exception {
assertSame("Version.getSession() did not return the right session", superuser, version.getSession());
}
/**
* Tests if <code>Version.getVersionHistory()</code> throws an {@link
* javax.jcr.UnsupportedRepositoryOperationException}
*/
public void testGetVersionHistory() throws Exception {
try {
version.getVersionHistory();
fail("Version.getVersionHistory() did not throw an UnsupportedRepositoryOperationException");
} catch (UnsupportedRepositoryOperationException success) {
}
}
/**
* Tests if <code>Version.getUUID()</code> returns the right UUID
*/
public void testGetUUID() throws Exception {
List successorValues = Arrays.asList(versionableNode.getVersionHistory().getRootVersion().getProperty(jcrSuccessors).getValues());
assertTrue("Version.getUUID() did not return the right UUID", successorValues.contains(superuser.getValueFactory().createValue(version)));
}
/**
* Tests if <code>Version.hasNode(String)</code> returns the right
* <code>boolean</code> value
*/
public void testHasNode() throws Exception {
assertTrue("Version.hasNode(String) did not return true", version.hasNode(jcrFrozenNode));
}
/**
* Tests if <code>Version.hasNodes()</code> returns <code>true</code>
*/
public void testHasNodes() throws Exception {
assertTrue("Version.hasNodes() did not return true", version.hasNodes());
}
/**
* Tests if <code>Version.hasProperties()</code> returns <code>true</code>
*/
public void testHasProperties() throws Exception {
assertTrue("Version.hasProperties() did not return true", version.hasProperties());
}
/**
* Tests if <code>Version.hasProperty(String)</code> returns the right
* <code>boolean</code> value
*/
public void testHasProperty() throws Exception {
assertTrue("Version.hasProperty(String) did not return true", version.hasProperty(jcrCreated));
}
/**
* Tests if <code>Version.holdsLock()</code> returns <code>false</code>
*/
public void testHoldsLock() throws Exception {
assertFalse("Version.holdsLock() did not return false", version.holdsLock());
}
/**
* Tests if <code>Version.isCheckedOut()</code> returns <code>true</code>
*/
public void testIsCheckedOut() throws Exception {
assertTrue("Version.isCheckedOut() did not return true", version.isCheckedOut());
}
/**
* Tests if <code>Version.isLocked()</code> returns <code>false</code>
*/
public void testIsLocked() throws Exception {
assertFalse("Version.isLocked() did not return false", version.isLocked());
}
/**
* Tests if <code>Version.isModified()</code> returns <code>false</code>
*/
public void testIsModified() throws Exception {
assertFalse("Version.isModified() did not return false", version.isModified());
}
/**
* Tests if <code>Version.isNew()</code> returns <code>false</code>
*/
public void testIsNew() throws Exception {
assertFalse("Version.isNew() did not return false", version.isNew());
}
/**
* Tests if <code>Version.isNode()</code> returns <code>true</code>
*/
public void testIsNode() throws Exception {
assertTrue("Version.isNode() did not return true", version.isNode());
}
/**
* Tests if <code>Version.isNodeType(String)</code> returns the right
* <code>boolean</code> value
*/
public void testIsNodeType() throws Exception {
assertTrue("Version.isNodeType(String) did not return true for nt:version", version.isNodeType(ntVersion));
}
/**
* Tests if <code>Version.isSame()</code> returns the right
* <code>boolean</code> value
*/
public void testIsSame() throws Exception {
assertTrue("Version.isSame(Item) did not return true", version2.isSame(versionableNode.getBaseVersion()));
}
/**
* Tests if <code>Version.lock(boolean, boolean)</code> throws a {@link
* LockException}
*/
public void testLock() throws Exception {
try {
version.lock(true, true);
fail("Version should not be lockable: Version.lock(true,true) did not throw a LockException");
} catch (LockException success) {
}
try {
version.lock(true, false);
fail("Version should not be lockable: Version.lock(true,false) did not throw a LockException");
} catch (LockException success) {
}
try {
version.lock(false, true);
fail("Version should not be lockable: Version.lock(false,true) did not throw a LockException");
} catch (LockException success) {
}
try {
version.lock(false, false);
fail("Version should not be lockable: Version.lock(false,false) did not throw a LockException");
} catch (LockException success) {
}
}
/**
* Tests if <code>Version.merge(String)</code> throws an
* {@link javax.jcr.nodetype.ConstraintViolationException}
*/
public void testMerge() throws Exception {
try {
version.merge(workspaceName, true);
fail("Version.merge(String, true) did not throw an ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
try {
version.merge(workspaceName, false);
fail("Version.merge(String, false) did not throw an ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
}
/**
* Tests if <code>Version.orderBefore(String, String)</code> throws an
* {@link javax.jcr.UnsupportedRepositoryOperationException}
*/
public void testOrderBefore() throws Exception {
try {
version.orderBefore(jcrFrozenNode, null);
fail("Version.orderBefore(String,String) did not throw an UnsupportedRepositoryOperationException or a ConstraintViolationException");
} catch (UnsupportedRepositoryOperationException success) {
} catch (ConstraintViolationException success) {
}
}
/**
* Tests if <code>Version.refresh(boolean)</code> works as expected (do
* nothing and return quietly)
*/
public void testRefresh() throws Exception {
// should do nothing and return quietly
version.refresh(true);
version.refresh(false);
}
/**
* Tests if <code>Version.remove()</code> throws an {@link
* javax.jcr.nodetype.ConstraintViolationException}
*/
public void testRemove() throws Exception {
try {
version.remove();
versionableNode.getVersionHistory().save();
fail("Version should be read-only: Version.remove() did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
}
/**
* Tests if <code>Version.removeMixin(String)</code> throws an {@link
* javax.jcr.nodetype.ConstraintViolationException}
*/
public void testRemoveMixin() throws Exception {
try {
version.removeMixin(mixVersionable);
fail("Version should be read-only: Version.removeMixin(String) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
}
/**
* Tests if <code>Version.restore(String, boolean)</code> and
* <code>Version.restore(Version, boolean)</code> throw an
* {@link UnsupportedRepositoryOperationException} and
* <code>Version.restore(Version, String, boolean)</code> throws a
* {@link ConstraintViolationException}.
*/
public void testRestore() throws Exception {
try {
version.restore("abc", true);
fail("Version.restore(String,boolean) did not throw an UnsupportedRepositoryOperationException");
} catch (UnsupportedRepositoryOperationException success) {
}
try {
version.restore(version2, true);
fail("Version.restore(Version,boolean) did not throw an UnsupportedRepositoryOperationException");
} catch (UnsupportedRepositoryOperationException success) {
}
try {
version.restore(version2, "abc", true);
fail("Version.restore(Version,String,boolean) did not throw an ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
}
/**
* Tests if <code>Version.restoreByLabel(String, boolean)</code> throws an
* {@link javax.jcr.UnsupportedRepositoryOperationException}
*/
public void testRestoreByLabel() throws Exception {
try {
version.restoreByLabel("abc", true);
fail("Version.restoreByLabel(String,boolean) did not throw an UnsupportedRepositoryOperationException");
} catch (UnsupportedRepositoryOperationException success) {
}
}
/**
* Tests if
* <ul> <li><code>Version.setProperty(String, String[])</code></li>
* <li><code>Version.setProperty(String, String[], int)</code></li>
* <li><code>Version.setProperty(String, Value[])</code></li>
* <li><code>Version.setProperty(String, Value[], int)</code></li>
* <li><code>Version.setProperty(String, boolean)</code></li>
* <li><code>Version.setProperty(String, double)</code></li>
* <li><code>Version.setProperty(String, InputStream)</code></li>
* <li><code>Version.setProperty(String, String)</code></li>
* <li><code>Version.setProperty(String, Calendar)</code></li>
* <li><code>Version.setProperty(String, Node)</code></li>
* <li><code>Version.setProperty(String, Value)</code></li>
* <li><code>Version.setProperty(String, long)</code></li>
* </ul> all throw a
* {@link javax.jcr.nodetype.ConstraintViolationException}
*/
public void testSetProperty() throws Exception {
// create Value[] object
Value[] vArray = new Value[3];
vArray[0] = superuser.getValueFactory().createValue("abc");
vArray[1] = superuser.getValueFactory().createValue("xyz");
vArray[2] = superuser.getValueFactory().createValue("123");
// create String array
String[] s = {"abc", "xyz", "123"};
try {
version.setProperty(propertyName1, s);
version.save();
fail("Version should be read-only: Version.setProperty(String,String[]) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
try {
version.setProperty(propertyName1, s, PropertyType.STRING);
version.save();
fail("Version should be read-only: Version.setProperty(String,String[],int) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
try {
version.setProperty(propertyName1, vArray);
version.save();
fail("Version should be read-only: Version.setProperty(String,Value[]) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
try {
version.setProperty(propertyName1, vArray, PropertyType.STRING);
version.save();
fail("Version should be read-only: Version.setProperty(String,Value[],int]) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
try {
version.setProperty(propertyName1, true);
version.save();
fail("Version should be read-only: Version.setProperty(String,boolean) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
try {
version.setProperty(propertyName1, 123);
version.save();
fail("Version should be read-only: Version.setProperty(String,double) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
try {
byte[] bytes = {73, 26, 32, -36, 40, -43, -124};
InputStream inpStream = new ByteArrayInputStream(bytes);
version.setProperty(propertyName1, inpStream);
version.save();
fail("Version should be read-only: Version.setProperty(String,InputStream) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
try {
version.setProperty(propertyName1, "abc");
version.save();
fail("Version should be read-only: Version.setProperty(String,String) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
try {
Calendar c = new GregorianCalendar(1945, 1, 6, 16, 20, 0);
version.setProperty(propertyName1, c);
version.save();
fail("Version should be read-only: Version.setProperty(String,Calendar) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
try {
version.setProperty(propertyName1, testRootNode);
version.save();
fail("Version should be read-only: Version.setProperty(String,Node) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
try {
Value v = superuser.getValueFactory().createValue("abc");
version.setProperty(propertyName1, v);
version.save();
fail("Version should be read-only: Version.setProperty(String,Value) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
try {
version.setProperty(propertyName1, -2147483650L);
version.save();
fail("Version should be read-only: Version.setProperty(String,long) did not throw a ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
}
/**
* Tests if <code>Version.unlock()</code> throws a {@link
* javax.jcr.lock.LockException}
*/
public void testUnlock() throws Exception {
try {
version.unlock();
fail("Version should not be lockable: Version.unlock() did not throw a LockException");
} catch (LockException success) {
}
}
/**
* Tests if <code>VersionHistory.update(String)</code> throws an
* {@link javax.jcr.nodetype.ConstraintViolationException}
*/
public void testUpdate() throws Exception {
try {
version.update(workspaceName);
fail("VersionHistory.update(String) did not throw an ConstraintViolationException");
} catch (ConstraintViolationException success) {
}
}
/**
* Tests if the jcr:frozenUuid property has the correct type
* @throws Exception
*/
public void testFrozenUUID() throws Exception {
Property p = version.getNode(jcrFrozenNode).getProperty(jcrFrozenUuid);
assertEquals("jcr:fronzenUuid should be of type string", PropertyType.TYPENAME_STRING, PropertyType.nameFromValue(p.getType()));
}
}